home *** CD-ROM | disk | FTP | other *** search
- integer initFlag, discrete, resetCon;
- integer newInput, newWant;
- real oldTime, maxVal, lastReset;
- real maxContents, maxTime;
- real timeArray[];
- real delayedInput; // from prev step for backward integration
- real delayedwantIn; // from prev step for backward integration
-
- // This block accumulates values and allows a specified
- // amount to be withdrawn
- // Copyright © 1989-1994 by Imagine That, Inc.
- // All Rights Reserved.
- // Extend Generic Library, Holding Tank block; Alfy Riddle
- // modified 3/1/92 JSL modified extensively for V2.0;
- // 4/1/92 BD for backward or forward euler
- // 12/8/92 JSL added currentStep == 0 to for reset
- // 1/14/92 JSL getOut Message handler doesn't recalc
- // 1/20/93 JSL changed inputCon to input val in calc
- // 1/20/93 JSL set contentsOut to not recalc from plotter
- // 1/20/93 JSL changed connector names
- // 2/26/93 JSL added sendMsgToOutputs(ConIn) to on conOut
- // 2/26/93 JSL added lastReset
- // 3/15/93 JSL replaced inputCon with inputVal
- // 10/15/93 BD changed integration to Euler standard
- // 10/26/93 BD added Euler forward for science
- // 10/27/93 BD fixed animation level
- // 2/14/94 DJK modified trace and report
- // 3/10/94 DJK added block label to report & trace
- // 5/18/94 BD changed dialog, help and fixed bug in forward
-
-
- procedure calc()
- {
- real numRemoved; // number requested to remove
- real timeStep; // for integration
- real inputVal, wantVal;
-
- if (OpIntegrate || OpIntegrateSci) // for integration
- {
- if (OpIntegrateSci) // for science
- {
- delayedInput = ConIn; // use forward Euler
- delayedwantIn = wantIn;
- }
-
- if (noValue(delayedInput))
- delayedInput = 0.0;
-
- if (noValue(delayedwantIn))
- delayedwantIn = 0.0;
-
- timeStep = CurrentTime-oldTime; // allows use in discrete evt
-
- if( ((currentStep == 0 && !resetCon) || resetIn > 0.5) && lastReset != currentTime)
- {
- if( initFlag )
- {
- if( noValue(initIn) )
- {
- userError("BLANK value at s input in Holding Tank block number "+(MyBlockNumber()));
- abort;
- }
-
- contents = initIn; // use connector for starting value if connected
- levelInit = contents;
- }
- else
- contents = levelInit; // use dialog box value
-
- lastReset = currentTime;
-
- if (OpIntegrateSci) // 5/18/94 BD if forward integration
- {
- // integrate input, numRemoved
- inputVal = delayedInput*timeStep;
- numRemoved = delayedwantIn*timeStep;
- }
- else // needs inputs zeroed
- {
- inputVal = 0.0;
- numRemoved = 0.0;
- }
- }
- else
- {
- // integrate input, numRemoved
- inputVal = delayedInput*timeStep;
- numRemoved = delayedwantIn*timeStep;
- }
-
- oldTime = CurrentTime;
- }
- else
- {
- if ( ((currentStep == 0 && !resetCon) || resetIn > 0.5) && lastReset != currentTime) // 12/8/92 Added currentStep
- {
- if( initFlag )
- {
- if( noValue(initIn) )
- {
- userError("BLANK value at s input in Holding Tank block number "+(MyBlockNumber()));
- abort;
- }
- contents = initIn; // use connector for starting value if connected
- levelInit = contents;
- }
- else
- contents = levelInit; // use dialog box value
- lastReset = currentTime;
- }
-
- // check input connectors for NoValues
- if(noValue(wantIn)) // NANs do not change contents
- numRemoved = 0.0;
- else
- numRemoved = wantIn; // if sum, timestep is 1.0
-
- if(noValue(ConIn)) // NANs do not change contents
- inputVal = 0.0;
- else
- inputVal = conIn; // if sum, timestep is 1.0
- }
-
- if (discrete && !newInput)
- inputVal = 0.0;
- newInput = FALSE;
-
- if (discrete && !newWant)
- numRemoved = 0.0;
- newWant = FALSE;
-
- if((contents + inputVal > numRemoved) OR canGoNeg) // lower limit at zero?
- contents += (inputVal - numRemoved); // ok for integration
- else
- {
- numRemoved = contents+inputVal;
- if (numRemoved < 0)
- numRemoved = 0;
- contents = 0;
- }
-
- if (contents > maxVal) // increase maximum if necessary
- maxVal = contents;
- if (contents > maxContents) // this will remember a smaller max level
- maxContents = contents; // remember max level from this run
-
- animationShow(1);
- if (maxVal <= 0.0)
- animationLevel(1, 0);
- else
- animationLevel(1, contents/ maxVal);
-
- getOut = numRemoved;
- contentsOut = contents;
-
- // sysGlobal2 is the file reference number for the DEBUG TRACE
- if( sysGlobal2 != 0.0 ) // 0 is error, check for open file for TRACE
- {
- // template for report: |BLOCK NAME *****************|block number |BLOCK NUMBER*******
- fileWrite(sysGlobal2,"Holding Tank block number "+(MyBlockNumber())+". Current Time:"+currentTime+".","",True);
- if(getBlockLabel(myBlockNumber()) != "")
- fileWrite(sysGlobal2,"Block Label: "+getBlockLabel(myBlockNumber()),"",True);
- fileWrite(sysGlobal2," Input = "+conIn,"",True);
- fileWrite(sysGlobal2," Contents = "+contentsOut,"",True);
- fileWrite(sysGlobal2," Output Wanted = "+wantIn,"",True);
- fileWrite(sysGlobal2," Output = "+getOut,"",True);
- fileWrite(sysGlobal2," Start Input = "+initIn,"",True);
- fileWrite(sysGlobal2," Reset Input = "+resetIn,"",True);
- fileWrite(sysGlobal2," ","",True);
- }
-
- if (OpIntegrate)
- {
- delayedInput = conIn; // 4/1/92 BD backward
- delayedwantIn = wantIn; // 4/1/92 BD backward
- }
- }
-
- // These connector messages are only called when this block is used in a
- // Discrete Event Model.
-
- on ConIn
- {
- sendMsgToOutputs(resetIn);
- sendMsgToOutputs(initIn);
- sendMsgToOutputs(wantIn);
- newInput = TRUE;
- calc();
- sendMsgToInputs(contentsOut);
- sendMsgToInputs(getOut);
- }
-
- // These connector messages are only called when this block is used in a
- // Discrete Event Model.
-
- on ResetIn
- {
- sendMsgToOutputs(ConIn);
- sendMsgToOutputs(initIn);
- sendMsgToOutputs(wantIn);
- calc();
- sendMsgToInputs(contentsOut);
- sendMsgToInputs(getOut);
- }
-
- // These connector messages are only called when this block is used in a
- // Discrete Event Model.
-
- on wantIn
- {
- sendMsgToOutputs(resetIn);
- sendMsgToOutputs(initIn);
- sendMsgToOutputs(ConIn);
- newWant = TRUE;
- calc();
- sendMsgToInputs(contentsOut);
- sendMsgToInputs(getOut);
- }
-
- // These connector messages are only called when this block is used in a
- // Discrete Event Model.
-
- on initIn
- {
- sendMsgToOutputs(resetIn);
- sendMsgToOutputs(ConIn);
- sendMsgToOutputs(wantIn);
- calc();
- sendMsgToInputs(contentsOut);
- sendMsgToInputs(getOut);
- }
-
- // These connector messages are only called when this block is used in a
- // Discrete Event Model.
-
- on contentsOut
- {
- // if the message is not coming from a plotter
- if (sysGlobalint9 == 0)
- {
- sendMsgToOutputs(conIn);
- sendMsgToOutputs(resetIn);
- sendMsgToOutputs(initIn);
- sendMsgToOutputs(wantIn);
- calc();
- sendMsgToInputs(getOut);
- }
- }
-
- // These connector messages are only called when this block is used in a
- // Discrete Event Model.
-
- on getOut
- {
- // this message handler doesn't recalc anymore.
- }
-
-
- // This message occurs for each step in the simulation.
- on simulate
- {
- calc();
- }
-
-
- // If the dialog data is inconsistent for simulation, abort.
- on checkdata
- {
- sysGlobal1 = 0.0; // prevent false reports
- sysGlobal2 = 0.0; // prevent false debugs
-
- initFlag = initIn;
- resetCon = resetIn;
-
- if( noValue(levelInit) AND !initFlag )
- {
- userError("Put a value in the Starting Contents in Holding Tank block number "+(MyBlockNumber()));
- abort;
- }
- }
-
-
- on createBlock
- {
- levelInit = 0;
- canGoNeg = 0;
-
- OpSum = TRUE; // add integration
- maxVal = 0.0;
- maxContents = 0.0;
- }
-
-
- // Initialize any simulation variables.
- on initsim
- {
- contents = levelInit;
-
- maxVal = maxContents; // start from max remembered from last run
-
- if (maxVal == 0.0)
- maxVal = levelInit;
-
- animationLevel(1, 0);
- animationColor(1, 30000, 30000, 30000, 1);
- if (animationOn)
- animationShow(1);
- else
- animationHide(1, FALSE);
- maxTime = endTime - startTime;
- maxContents = 0.0; // reset it to remember max level
- delayedInput = 0.0;
- delayedwantIn = 0.0;
- lastReset = BLANK;
-
- discrete = FALSE;
- if( getPassedArray(sysGlobal0, timeArray) )
- {
- getSimulateMsgs(FALSE);
- discrete = TRUE;
- }
- newInput = FALSE;
- newWant = FALSE;
-
- if (discrete)
- oldTime = startTime; // discrete
- else
- oldTime = startTime-deltaTime; // continuous
- }
-
-
- on endSim
- {
- // sysGlobal1 is the file reference number for the TEXT REPORT
- if( sysGlobal1 != 0.0 ) // 0 is error, check for open file for REPORT
- {
- // template for report: |BLOCK NAME *****************|block number |BLOCK NUMBER*******
- fileWrite(sysGlobal1,"Holding Tank block number "+MyBlockNumber(),"",True);
- if(getBlockLabel(myBlockNumber()) != "")
- fileWrite(sysGlobal1,"Block Label: "+getBlockLabel(myBlockNumber()),"",True);
- fileWrite(sysGlobal1," Starting Contents = "+levelInit,"",True);
- fileWrite(sysGlobal1," Final Contents = "+contents,"",True);
- if( canGoNeg )
- fileWrite(sysGlobal1," Output wanted can take tank negative","",True);
-
- if( comments != "" )
- fileWrite(sysGlobal1," Comments = "+comments,"",True);
-
- fileWrite(sysGlobal1," ","",True);
- }
- }